package org.ws.httphelper.support.pipeline.handler.request;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.ws.httphelper.common.PropertyUtil;
import org.ws.httphelper.core.pipeline.HandlerOrder;
import org.ws.httphelper.core.pipeline.RequestHandler;
import org.ws.httphelper.exception.RequestException;
import org.ws.httphelper.model.RequestContext;
import org.ws.httphelper.model.config.RequestConfig;
import org.ws.httphelper.model.field.ParamField;

import java.beans.IntrospectionException;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 参数验证处理器
 */
@HandlerOrder(value = 0,level = HandlerOrder.OrderLevel.SYSTEM)
public class ValidationParamHandler implements RequestHandler {

    private static Logger log = LoggerFactory.getLogger(ValidationParamHandler.class.getName());

    @Override
    public boolean handler(RequestContext requestContext) throws RequestException {
        Object in = requestContext.getInput();
        if(in == null){
            return true;
        }
        RequestConfig requestConfig = requestContext.getRequestConfig();
        Map<String, ParamField> paramFields = requestConfig.getParamFields();
        for (ParamField field : paramFields.values()) {
            String fieldName = field.getFieldName();
            Object defaultValue = field.getDefaultValue();
            String validation = field.getValidation();
            Object value = null;
            try {
                value = getValue(in,fieldName);
            } catch (Exception e) {
                throw new RequestException(e.getMessage(),e);
            }
            if(value == null && defaultValue != null){
                value = defaultValue;
            }
            if(field.isRequired()){
                if(value == null){
                    throw new RequestException(fieldName+" is required.");
                }
            }
            if(StringUtils.isNoneBlank(validation) && value != null){
                if(!Pattern.matches(validation,String.valueOf(value))){
                    throw new RequestException(fieldName+"["+value+"] is not match["+validation+"].");
                }
            }
        }

        return true;
    }

    private Object getValue(Object in,String name) throws IntrospectionException {
        if(in instanceof Map){
            return ((Map)in).get(name);
        }
        else {
            return PropertyUtil.getValue(in,name);
        }
    }

}
